package com.oazon.moco.serialport;

import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;

import com.moco.launcher.bean.MOCO_CONSTANTS;
import com.moco.launcher.link.LinkManager;
import com.oazon.common.Logger;
import com.oazon.common.util.BatteryUtil;
import com.oazon.common.util.SDcradUtil;
import com.oazon.common.util.TimeUtils;
import com.oazon.common.util.Utils;
import com.oazon.moco.bean.Metadata;
import com.oazon.moco.lan.core.http.bean.FavoriteBean;
import com.oazon.moco.link.core.LinkEventController;
import com.oazon.moco.link.core.LinkSDK;
import com.oazon.moco.link.core.source.LinkEventSource;
import com.oazon.moco.link.serialport.PlayerEventListener;
import com.oazon.moco.link.serialport.ResponceEventListener;
import com.oazon.moco.link.serialport.SerialBatteryEventListener;
import com.oazon.moco.link.serialport.SpechEventListener;
import com.oazon.moco.link.serialport.SystemStateEventListener;
import com.oazon.moco.playlist.PlayListManage;
import com.oazon.moco.serialport.core.Pack;
import com.oazon.moco.serialport.core.Serial;
import com.oazon.system.bean.SystemState;

public class SerialHandlerService extends Service {
	
	private static String TAG = "SerialHandlerService";
	LinkSDK linkSDk = LinkSDK.getInstance();
	private static SerialBatteryEventListener batterylistener = new SerialBatteryEventListener(
			LinkEventController.serialSource);
	private static ResponceEventListener responselistener = new ResponceEventListener(
			LinkEventController.serialSource);
	private static PlayerEventListener playerEventListener = new PlayerEventListener(
			new LinkEventSource());
	private static SpechEventListener spechEventListener = new SpechEventListener(
			LinkEventController.serialSource);
	private static SystemStateEventListener systemStateEventListener = new SystemStateEventListener(
			LinkEventController.serialSource,LinkEventController.uiSource,LinkEventController.lanSource);
	
	public static final byte MCU_BAT_CHARGING_STATUS = (byte) 0x81; // 电池充电 MCU
																	// 0x81
	public static final byte MCU_BAT_FULL_STATUS = (byte) 0x82; // 电池充满 MCU 0x82
	public static final byte CMD_RTN_BAT_LEVEL = (byte) 0x6D; // 电池电量百分比 MCU
																// 0x83
	public static final byte CMD_RTN_IS_DC_IN = (byte) 0x6E; // DC外部电源是否插入
	public static final byte CMD_RTN_IS_BAT_CHARGING = (byte) 0x6B; // DC外部电源是否插入
	//协议里面没发现这个描述，先去掉了
	//public static final byte M_VOLUM_FIND = (byte) 0x85; // MCU查询音量大小 MCU 0x85
	public static final byte M_FIND_S_SATATE = (byte) 0x86; // MCU查询上位机工作状态 MCU
	public static final byte MCU_KEY_VOL_UP = (byte) 0x87; // 音量+
	public static final byte MCU_KEY_VOL_DOWN = (byte) 0x88; // 音量+
	public static final byte MCU_KEY_PLAYPAUSE = (byte) 0x89; // 播放状态改变
	public static final byte MCU_KEY_PREV = (byte) 0x8A; // 上一首
	public static final byte MCU_KEY_NEXT = (byte) 0x8B; // 下一首
	public static final byte MCU_KEY_VOICE_CMD_PRESSED = (byte) 0x8D; // 语音开始
	public static final byte MCU_KEY_VOICE_CMD_RELEASED = (byte) 0x8E; // 语音 结束
	public static final byte CMD_RTN_VERSION = (byte) 0x61; // 获取MCU软硬件版本号
	public static final byte MCU_KEY_TOP = (byte) 0x8F; // 用户短按了一下TOP按钮并松开
	public static final byte CMD_RTN_MICROWAVE_ACTIVE = (byte) 0x70; // 微波感应 近
	public static final byte M_VOLUM_NUMBER = (byte) 0x6A; // 微波感应 近
	public static final byte CMD_RTN_BATTERY_VOLTAGE = (byte) 0x85;//返回电压值
	
	public boolean b = false;
	public static int countShift = 0;
	Serial serialEngine;
	Timer systemTimer = null;
	Timer watchdogTimer = null;

	public static boolean StopWatchDog = false;

	@SuppressLint("HandlerLeak")
	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {

			switch (msg.what) {
			case 1:
				Pack p = (Pack) msg.obj;
				// Toast.makeText(SerialHandlerService.this,
				// byteToString(p.tobytes()), Toast.LENGTH_SHORT).show();
				if (p.getType() == (byte) 0x00) {
				} else {
					handlerpack(p);
				}
				break;
			default:
				break;
			}
		};
	};

	Handler statHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (msg.what == 0x123) {
				if (countShift > 1) {
				
					ActivityManager activityManager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
			        String runningActivity=activityManager.getRunningTasks(1).get(0).topActivity.getClassName();  
			        
			        if(runningActivity.equals("com.moco.launcher.activity.WelcomeActivity")){
			        	return;
			        }
					countShift = 0;
					Logger.d(TAG, "喜欢本首歌曲");

					Metadata currentMedia = PlayListManage.getInstance().getCurrentMedia();
					if(currentMedia == null) {
						Logger.e(TAG, "currentMedia in null");
						return;
					}
					if(currentMedia.isFavorite()){
						Toast.makeText(SerialHandlerService.this, "已经收藏", Toast.LENGTH_SHORT).show();
						return;
					}
					String provider = currentMedia.getServiceID();
					String itemId = currentMedia.getItemID();

					if (itemId == null) {
						Logger.e(TAG, "currentMedia id is null");
						return;
					}
					if (provider == null
							|| provider.equals(MOCO_CONSTANTS.RECOMMEND_ROOT)) {
						provider = "";
					}

					FavoriteBean favoriteBean = new FavoriteBean();
					favoriteBean.setLike(true);
					favoriteBean.setProvider(provider);
					favoriteBean.setCurrentItemID(itemId);
					Logger.i(TAG, provider+"provider");
					Logger.i(TAG, itemId+"itemId");
					Logger.i(TAG, provider+"provider");
					LinkSDK.getInstance().favorite(
							LinkEventController.serialSource, favoriteBean);
				} else {
					countShift = 0;
				}
				
			}
		}

	};

	static int i = 0;
	AnrReceiver anrReceiver = null;

	@Override
	public void onCreate() {
		super.onCreate();

		serialEngine = Serial.getInstance();
		serialEngine.setHandler(handler);
		serialEngine.start();
		register();
		initTimer();

		anrReceiver = new AnrReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.intent.action.ANR");
		filter.addAction("com.moco.noanr");
		registerReceiver(anrReceiver, filter);

	}

	static boolean IS_ANR = false;

	class AnrReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context arg0, Intent intent) {
			if (intent.getAction().equals("android.intent.action.ANR")) {
				int pid = intent.getIntExtra("pid", 0);
				if (pid != 0 && pid == android.os.Process.myPid()) {
					Logger.d(TAG, "android.intent.action.ANR pid:" + pid);
					IS_ANR = true;
				}
			} else if (intent.getAction().equals("com.moco.noanr")) {
				int pid = intent.getIntExtra("pid", 0);
				boolean notResponding = intent.getBooleanExtra("notResponding",
						false);
				if (pid != 0 && pid == android.os.Process.myPid()
						&& !notResponding) {
					Logger.d(TAG, "com.moco.noanr pid:" + pid);
					IS_ANR = false;
				}
			}
		}
	}

	public static void  stopWatchDog() {
		StopWatchDog = true;
		SerialSend.getInstance().sendStatus(SerialSend.Serial_WATCHDOG_CLOSE);
	}

	public static void  startWatchDog() {
		StopWatchDog = false;
		SerialSend.getInstance().sendStatus(SerialSend.Serial_WATCHDOG_OPEN);
	}

	private void initTimer() {
		if (systemTimer == null) {
			systemTimer = new Timer();
			TimerTask task = new TimerTask() {
				@Override
				public void run() {
					SerialSend.getInstance().sendStatus(
							SerialSend.Serial_POWER_PERCENT);
					SerialSend.getInstance().sendStatus(
							SerialSend.Serial_POWER_EXTERNAL);
					SerialSend.getInstance().sendStatus( 
							SerialSend.Serial_POWER_CHARGE);
					SerialSend.getInstance().sendStatus(
							SerialSend.Serial_GET_BATTERY_VOLTAGE);
				}
			};
			systemTimer.schedule(task, 0, 5 * 60 * 1000);
		}

		if (watchdogTimer == null) {
			watchdogTimer = new Timer();
			TimerTask dog = new TimerTask() {
				@Override
				public void run() {
					Logger.d("michael", "watchdogTimer: "
							+ Thread.currentThread().getName());
					if (LinkManager.getInstance().getSaveSystemState() != SystemState.SHUTDOWN
							&& !IS_ANR
							&& !StopWatchDog) {
						SerialSend.getInstance().sendStatus(
								SerialSend.Serial_WATCHDOG_OPEN);
					}
				}
			};
			watchdogTimer.schedule(dog, 0, 5 * 1000);
		}
	}

	@Override
	public IBinder onBind(Intent arg0) {

		return null;
	}

	// TODO:remove LinkSDK.getInstance().hasAction to a listener
	public void handlerpack(Pack p) {
		switch (p.getType()) {
		case MCU_BAT_CHARGING_STATUS:
			chargingStatus(p);
			break;
		case MCU_BAT_FULL_STATUS:
			fullStatus(p);
			break;
		case CMD_RTN_BAT_LEVEL:
			batLevel(p);
			break;
		case CMD_RTN_IS_DC_IN:
			dcIn(p);
			break;
		case CMD_RTN_IS_BAT_CHARGING:
			batCharging(p);
			break;
		/*case M_VOLUM_FIND:
			volumFind(p);
			break;*/
		case M_FIND_S_SATATE:
			findSState(p);
			break;
		case MCU_KEY_VOL_UP:
			volUp(p);
			break;
		case MCU_KEY_VOL_DOWN:
			volDown();
			break;
		case MCU_KEY_PLAYPAUSE:
			playPause();
			break;
		case MCU_KEY_TOP:
			keyTop();
			break;
		case MCU_KEY_PREV:
			keyPrev();
			break;
		case MCU_KEY_NEXT:
			keyNext();
			break;
		case MCU_KEY_VOICE_CMD_PRESSED:
			keyVoicePressed();
			break;
		case MCU_KEY_VOICE_CMD_RELEASED:
			keyVoiceReleased();
			break;
		case CMD_RTN_VERSION:
			rtnVersion(p);
			break;
		case CMD_RTN_BATTERY_VOLTAGE:
			rtnBatteryVoltage(p);
			break;
		default:
			Logger.d(TAG, "default");
			break;
		}
	}

	private void rtnVersion(Pack p) {
		if (!SerialControll.getInstance().isCanHardwareVersion()) {
			return;
		}
		Logger.d(TAG, "S_HARDWARE_VERSION");
		linkSDk.responseHardWareVersion(LinkEventController.serialSource,
				byteToString(p.getData()));

	}

	private void keyVoiceReleased() {
		if (!SerialControll.getInstance().isCanSpeechEnd()) {
			return;
		}
		Logger.d(TAG, "M_SPEECH_END");
		// s_linkSDk.speechStop(LinkEventController.serialSource);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void keyVoicePressed() {
		if (!SerialControll.getInstance().isCanSpeechStart()) {
			return;
		}
		ActivityManager activityManager=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
        String runningActivity=activityManager.getRunningTasks(1).get(0).topActivity.getClassName();  
        
        if(runningActivity.equals("com.moco.launcher.activity.WelcomeActivity")){
        	return;
        }
		Logger.d(TAG, "M_SPEECH_START");
		linkSDk.speechStart(LinkEventController.serialSource);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void keyNext() {
		if (!SerialControll.getInstance().isCanNext()) {
			return;
		}
		Logger.d(TAG, "M_NEXT");
		linkSDk.next(LinkEventController.serialSource, -1);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void keyPrev() {
		if (!SerialControll.getInstance().isCanPrevious()) {
			return;
		}
		Logger.d(TAG, "M_PREVIOUS");
		linkSDk.previous(LinkEventController.serialSource, -1);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void keyTop() {
		if (!SerialControll.getInstance().isCanSpeechHold()) {
			return;
		}
		Logger.d(TAG, "M_SPEECH_HOLD");
		countShift = countShift + 1;
		Logger.d(TAG, "count_shift==" + countShift);
		if (countShift == 1) {
			statHandler.sendEmptyMessageDelayed(0x123, 1000);
		}
	}

	private void playPause() {
		if (!SerialControll.getInstance().isCanShift()) {
			return;
		}
		Logger.d(TAG, "M_SHIFT");
		linkSDk.shift(LinkEventController.serialSource);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void volDown() {
		if (!SerialControll.getInstance().isCanVolDown()) {
			return;
		}
		Logger.d(TAG, "M_VOLUM_DOWN");
		linkSDk.volumeDown(LinkEventController.serialSource);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);
	}

	private void volUp(Pack p) {
		if (!SerialControll.getInstance().isCanVolUp()) {
			return;
		}
		Logger.d(TAG, "M_VOLUM_UP");
		linkSDk.volumeUp(LinkEventController.serialSource);
		LinkSDK.getInstance().hasAction(LinkEventController.uiSource);

	}

	private void findSState(Pack p) {
		if (!SerialControll.getInstance().isCanFindSState()) {
			return;
		}
		Logger.d(TAG, "M_FIND_S_SATATE");
		linkSDk.requestState(LinkEventController.serialSource);

	}

	/*private void volumFind(Pack p) {
		if (!SerialControll.getInstance().isCanVolFind()) {
			return;
		}
		Logger.d(TAG, "M_VOLUM_FIND");
		linkSDk.requestVolume(LinkEventController.serialSource, -1);
	}*/

	private void batCharging(Pack p) {
		if (!SerialControll.getInstance().isCanBatCharging()) {
			return;
		}
		int isCharing = Pack.readOne(p.getData());
		Logger.d(TAG, "CMD_RTN_IS_BAT_CHARGING:" + isCharing);
		String text = "";
		if (isCharing == 0) {
			text ="未充电";
			linkSDk.setChageOff(LinkEventController.serialSource);
		} else if (isCharing == 1) {
			text ="正在充电";
			linkSDk.setChageOn(LinkEventController.serialSource);
		}
		try {
			SDcradUtil.saveToSDCard(TAG+".txt", "CMD_RTN_IS_BAT_CHARGING:=" + text +"|time ===="+TimeUtils.getCurrentTimeSec(),getApplicationContext());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void dcIn(Pack p) {
		if (!SerialControll.getInstance().isCanDCIn()) {
			return;
		}
		int e_power = Pack.readOne(p.getData());
		Logger.d(TAG, "CMD_RTN_IS_DC_IN: " + e_power);
		String text = "";
		if (e_power == 0) {
			text="电源未插入";
			linkSDk.setExternalPowerOut(LinkEventController.serialSource);
		} else if (e_power == 1) {
			text="电源已插入";
			linkSDk.setExternalPowerIn(LinkEventController.serialSource);
		}
		try {
			SDcradUtil.saveToSDCard(TAG+".txt", "CMD_RTN_IS_DC_IN:=" + text +"|time ===="+TimeUtils.getCurrentTimeSec(),getApplicationContext());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void batLevel(Pack p) {
		if (!SerialControll.getInstance().isCanPowerPercent()) {
			return;
		}
		int percent = Pack.readOne(p.getData());
		try {
			SDcradUtil.saveToSDCard(TAG+".txt", "POWER_PERCENT:" + percent+"%|time ===="+TimeUtils.getCurrentTimeSec(),getApplicationContext());
		} catch (Exception e) {
			e.printStackTrace();
		}
//		percent = BatteryUtil.batteryProcess(percent);
		Logger.d(TAG, "M_POWER_PERCENT:" + percent+"%|time ===="+TimeUtils.getCurrentTimeSec());
		linkSDk.setChagePercent(LinkEventController.serialSource, percent);

	}

	private void fullStatus(Pack p) {
		if (!SerialControll.getInstance().isCanPowerFull()) {
			return;
		}
		int b = Pack.readOne(p.getData());
		Logger.d(TAG, "M_POWRR_FULL:" + b);
		if (b == 0) {
			linkSDk.setFullNo(LinkEventController.serialSource);
		} else if (b == 1) {
			linkSDk.setFullYes(LinkEventController.serialSource);
		}

	}

	private void chargingStatus(Pack p) {
		if (!SerialControll.getInstance().isCanPowerChange()) {
			return;
		}
		Logger.d(TAG, "M_POWER_CHARGE");
		int a = Pack.readOne(p.getData());
		if (a == 0) {
			linkSDk.setChageOff(LinkEventController.serialSource);
		} else if (a == 1) {
			linkSDk.setChageOn(LinkEventController.serialSource);
		}

	}

	private void rtnBatteryVoltage(Pack p){
		if (!SerialControll.getInstance().isCanRtnBatteryVoltage()) {
			return;
		}
		Logger.d(TAG, "RTN_BATTERY_VOLTAGE");
		float a = 0;
		if(p.getLen() == 1){
			a = (float) ((0x00FF & Pack.readOne(p.getData()))/10.0);
		}else if(p.getLen() == 2){
			a = (float) ((Pack.byteArrayToShort(p.getData()))/1000.0);
		}
		try {
			SDcradUtil.saveToSDCard(TAG+".txt", "POWER_VOLTAGE:=" + a +"|time ===="+TimeUtils.getCurrentTimeSec(),getApplicationContext());
		} catch (Exception e) {
			e.printStackTrace();
		}
		Logger.d(TAG, "=========voltage value:"+a);
		linkSDk.setVoltage(LinkEventController.serialSource, a);
	}
	
	public static String byteToString(byte[] b) {
		StringBuffer buffer = new StringBuffer(b.length);
		for (int i = 0; i < b.length; i++) {
			String strHex = Integer.toHexString(b[i]).toUpperCase();

			if (strHex.length() > 3) {
				buffer.append(strHex.substring(6) + " ");
			} else if (strHex.length() < 2) {
				buffer.append("0" + strHex + " ");
			} else {
				buffer.append(strHex + " ");
			}
		}
		return buffer.toString();
	}

	public void register() {
		b = true;
		linkSDk.registLinkListener(batterylistener);
		linkSDk.registLinkListener(responselistener);
		linkSDk.registLinkListener(playerEventListener);
		linkSDk.registLinkListener(spechEventListener);
		linkSDk.registLinkListener(systemStateEventListener);
	}

	public void unRisgter() {
		b = false;
		linkSDk.unregistLinkListener(batterylistener);
		linkSDk.unregistLinkListener(responselistener);
		linkSDk.unregistLinkListener(playerEventListener);
		linkSDk.unregistLinkListener(spechEventListener);
		linkSDk.unregistLinkListener(systemStateEventListener);
	}

	public boolean isGister() {
		return b;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		unRisgter();
		if (systemTimer != null) {
			systemTimer.cancel();
			systemTimer = null;
		}
		if (watchdogTimer != null) {
			watchdogTimer.cancel();
			watchdogTimer = null;
		}

		if (anrReceiver != null) {
			this.unregisterReceiver(anrReceiver);
		}
	}
}
